import cv2
from PyQt5.QtCore import QThread, pyqtSignal


class VideoProcessor(QThread):
    frame_ready = pyqtSignal(object)
    processing_result = pyqtSignal(str)

    def __init__(self):
        super().__init__()
        self.cap = None
        self.is_running = False
        self.processing_function = None
        self.current_frame = 0
        self.total_frames = 0

    def open_video(self, file_path):
        self.cap = cv2.VideoCapture(file_path)
        if not self.cap.isOpened():
            self.processing_result.emit("无法打开视频文件")
            return False

        self.total_frames = int(self.cap.get(cv2.CAP_PROP_FRAME_COUNT))
        self.current_frame = 0
        return True

    def open_camera(self, camera_id=0):
        self.cap = cv2.VideoCapture(camera_id)
        if not self.cap.isOpened():
            self.processing_result.emit("无法打开摄像头")
            return False

        self.total_frames = 0
        self.current_frame = 0
        return True

    def set_processing_function(self, func):
        self.processing_function = func

    def run(self):
        self.is_running = True
        while self.is_running:
            if self.cap and self.cap.isOpened():
                ret, frame = self.cap.read()
                if not ret:
                    self.processing_result.emit("视频播放完毕")
                    self.is_running = False
                    break

                self.current_frame += 1

                # 应用处理函数
                if self.processing_function:
                    try:
                        _, processed_frame = self.processing_function(frame)
                        self.frame_ready.emit(processed_frame)
                    except Exception as e:
                        self.processing_result.emit(f"处理视频帧时出错: {str(e)}")
                        self.frame_ready.emit(frame)
                else:
                    self.frame_ready.emit(frame)

                # 如果是文件视频且到达末尾，停止播放
                if self.total_frames > 0 and self.current_frame >= self.total_frames:
                    self.is_running = False

            # 控制帧率
            self.msleep(30)

    def play(self):
        if not self.is_running and self.cap and self.cap.isOpened():
            self.start()

    def pause(self):
        self.is_running = False
        if self.isRunning():
            self.wait()

    def stop(self):
        self.is_running = False
        if self.isRunning():
            self.wait()

        if self.cap:
            self.cap.release()
            self.cap = None
            self.current_frame = 0
            self.total_frames = 0

    def forward(self):
        if self.cap and self.cap.isOpened() and self.total_frames > 0:
            self.current_frame = min(self.current_frame + 10, self.total_frames - 1)
            self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.current_frame)

    def backward(self):
        if self.cap and self.cap.isOpened() and self.current_frame > 10:
            self.current_frame -= 10
            self.cap.set(cv2.CAP_PROP_POS_FRAMES, self.current_frame)